package com.tyk.bookstore.back.payment.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tyk.bookstore.back.common.core.model.type.BinVo;
import com.tyk.bookstore.back.common.core.util.ObjUtil;
import com.tyk.bookstore.back.member.model.dto.Member4PaymentDto;
import com.tyk.bookstore.back.member.service.MemberApiService;
import com.tyk.bookstore.back.order.service.OrderApiService;
import com.tyk.bookstore.back.payment.manager.excel.model.ShopStatementExcelVo;
import com.tyk.bookstore.back.payment.model.entity.ShopStatementDo;
import com.tyk.bookstore.back.payment.model.query.ShopStatementAddQuery;
import com.tyk.bookstore.back.payment.model.query.ShopStatementPageQuery;
import com.tyk.bookstore.back.payment.model.query.ShopStatementUpdateQuery;
import com.tyk.bookstore.back.payment.model.vo.ShopStatementPageVo;
import com.tyk.bookstore.back.payment.model.vo.ShopStatementVo;
import com.tyk.bookstore.back.payment.repository.ShopStatementRepository;
import com.tyk.bookstore.back.payment.service.ShopStatementService;
import com.tyk.bookstore.back.payment.util.MapStructPayment;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;


/**
 * @author tyk
 * @description 书店流水
 */
@Service
@RequiredArgsConstructor

public class ShopStatementServiceImpl implements ShopStatementService {

    private final ShopStatementRepository shopStatementRepository;
    private final MemberApiService memberApiService;
    private final OrderApiService orderApiService;
    private final MapStructPayment mapStructPayment;

    @Override
    public ShopStatementVo getById(Long id) {
        ShopStatementDo shopStatement = shopStatementRepository.selectById(id);
        return mapStructPayment.toShopStatementVo(shopStatement);
    }

    @Override
    public ShopStatementPageVo getPage(ShopStatementPageQuery query) {
        // 分页查询
        Page<ShopStatementDo> page = new Page<>(query.getPage(), query.getLimit());
        LambdaQueryWrapper<ShopStatementDo> w = buildPageQueryWrapper(query);
        shopStatementRepository.selectPage(page, w);
        // 来源主体信息
        Set<Long> midSet = page.getRecords().stream().map(ShopStatementDo::getOtherSideIdentification).collect(Collectors.toSet());
        Map<Long, Member4PaymentDto> mMap = memberApiService
                .getMember4PaymentDtoListByIdSet(midSet)
                .stream().collect(Collectors.toMap(
                        Member4PaymentDto::getId,
                        it -> it
                ));
        // 来源信息
        Set<Long> oidSet = page.getRecords().stream().map(ShopStatementDo::getSourceIdentification).collect(Collectors.toSet());
        Map<Long, String> oMap = orderApiService
                .getOrderNoListByIdSet(oidSet)
                .stream().collect(Collectors.toMap(
                        BinVo::getId,
                        BinVo::getValue
                ));
        // 补充信息
        List<ShopStatementPageVo.ShopStatement> records = page.getRecords().stream().map(it -> {
            ShopStatementPageVo.ShopStatement vo = mapStructPayment.toShopStatementPageVo$ShopStatement(it);
            Member4PaymentDto dto = mMap.get(it.getOtherSideIdentification());
            vo.setOtherSideIdentification(dto.getAccount());
            String orderNo = oMap.get(it.getSourceIdentification());
            vo.setSourceIdentification(orderNo);
            return vo;
        }).toList();
        // 返回
        ShopStatementPageVo pv = mapStructPayment.toShopStatementPageVo(page);
        pv.setRecords(records);
        return pv;
    }


    @Override
    public void add(ShopStatementAddQuery query) {
        ShopStatementDo shopStatement = mapStructPayment.toShopStatementDo(query);
        shopStatementRepository.insert(shopStatement);
    }

    @Override
    public void updateById(ShopStatementUpdateQuery query) {
        ShopStatementDo shopStatement = mapStructPayment.toShopStatementDo(query);
        shopStatementRepository.updateById(shopStatement);
    }

    @Override
    public void deleteById(Long id) {
        shopStatementRepository.deleteById(id);
    }

    @Override
    public void deleteBatchByIdSet(Set<Long> idSet) {
        shopStatementRepository.deleteBatchIds(idSet);
    }

    @Override
    public List<ShopStatementExcelVo> getShopStatementExcelVoList(ShopStatementPageQuery query) {
        LambdaQueryWrapper<ShopStatementDo> w = buildPageQueryWrapper(query);
        List<ShopStatementDo> doList = shopStatementRepository.selectList(w);
        return mapStructPayment.toShopStatementExcelVoList(doList);
    }

    private LambdaQueryWrapper<ShopStatementDo> buildPageQueryWrapper(ShopStatementPageQuery query) {

        LambdaQueryWrapper<ShopStatementDo> w = new LambdaQueryWrapper<>();

        // 来源标识
        if (ObjUtil.notBlank(query.getSourceIdentification())) {
            Long oid = orderApiService.getIdByOrderNo(query.getSourceIdentification());
            w.eq(ShopStatementDo::getSourceIdentification, oid);
        }

        // 来源主体标识
        if (ObjUtil.notBlank(query.getOtherSideIdentification())) {
            List<Long> midList = memberApiService.getIdListByKw(query.getOtherSideIdentification());
            w.in(ShopStatementDo::getOtherSideIdentification, midList);
        }

        // 交易值
        w.ge(query.getModificationFrom() != null, ShopStatementDo::getModification, query.getModificationFrom());
        w.ge(query.getModificationTo() != null, ShopStatementDo::getModification, query.getModificationTo());

        // 交易性质
        w.eq(query.getNature() != null, ShopStatementDo::getNature, query.getNature());

        // 交易类型
        w.eq(query.getType() != null, ShopStatementDo::getType, query.getType());

        // 创建时间
        w.ge(query.getCreateTimeFrom() != null, ShopStatementDo::getCreateTime, query.getCreateTimeFrom());
        w.le(query.getCreateTimeTo() != null, ShopStatementDo::getCreateTime, query.getCreateTimeTo());

        // 创建时间排序
        w.orderBy(true, false, ShopStatementDo::getCreateTime);

        return w;
    }

}

